#!/bin/bash

# QEMU K8s虚拟机管理工具
# 提供统一的虚拟机管理接口

set -e

# 加载配置文件
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SOURCE_DIR/config.conf"

# 颜色输出函数
red() { echo -e "\033[31m$1\033[0m"; }
green() { echo -e "\033[32m$1\033[0m"; }
yellow() { echo -e "\033[33m$1\033[0m"; }
blue() { echo -e "\033[34m$1\033[0m"; }
cyan() { echo -e "\033[36m$1\033[0m"; }

# 导入虚拟机到virt-manager
import_to_virtmanager() {
    local vm_name="$1"
    
    if [[ -z "$vm_name" ]]; then
        echo "$(red '错误: 请指定虚拟机名称')"
        return 1
    fi
    
    echo "$(blue '导入虚拟机 $vm_name 到virt-manager...')"
    
    # 调用导入脚本
    if [[ -f "$(dirname "$0")/import-to-virtmanager.sh" ]]; then
        "$(dirname "$0")/import-to-virtmanager.sh" import "$vm_name"
    else
        echo "$(red '错误: 导入脚本不存在')"
        return 1
    fi
}

# 导入所有虚拟机到virt-manager
import_all_to_virtmanager() {
    echo "$(blue '导入所有虚拟机到virt-manager...')"
    
    # 调用导入脚本
    if [[ -f "$(dirname "$0")/import-to-virtmanager.sh" ]]; then
        "$(dirname "$0")/import-to-virtmanager.sh" import-all
    else
        echo "$(red '错误: 导入脚本不存在')"
        return 1
    fi
}

# 启动virt-manager图形界面
start_virtmanager_gui() {
    echo "$(blue '启动virt-manager图形界面...')"
    
    # 调用导入脚本
    if [[ -f "$(dirname "$0")/import-to-virtmanager.sh" ]]; then
        "$(dirname "$0")/import-to-virtmanager.sh" gui
    else
        echo "$(red '错误: 导入脚本不存在')"
        return 1
    fi
}

# 显示帮助信息
show_help() {
    echo "$(blue 'QEMU K8s虚拟机管理工具')"
    echo
    echo "用法: $0 <命令> [参数]"
    echo
    echo "$(yellow '可用命令:')"
    echo "  list                    - 列出所有虚拟机"
    echo "  status [vm_name]        - 显示虚拟机状态"
    echo "  start <vm_name>         - 启动指定虚拟机"
    echo "  stop <vm_name>          - 停止指定虚拟机"
    echo "  restart <vm_name>       - 重启指定虚拟机"
    echo "  install <vm_name>       - 启动虚拟机安装模式"
    echo "  connect <vm_name>       - 显示VNC连接信息"
    echo "  monitor <vm_name>       - 连接到虚拟机监控器"
    echo "  delete <vm_name>        - 删除虚拟机"
    echo "  clone <src> <dst>       - 克隆虚拟机"
    echo "  backup <vm_name>        - 备份虚拟机"
    echo "  restore <vm_name> <backup> - 恢复虚拟机"
    echo "  import <vm_name>        - 导入虚拟机到virt-manager"
    echo "  import-all              - 导入所有虚拟机到virt-manager"
    echo "  virt-manager            - 启动virt-manager图形界面"
    echo "  network                 - 显示网络状态"
    echo "  cleanup                 - 清理所有虚拟机"
    echo
    echo "$(yellow '示例:')"
    echo "  $0 list"
    echo "  $0 status k8s-master1"
    echo "  $0 start k8s-master1"
    echo "  $0 stop k8s-worker1"
    echo "  $0 connect k8s-master1"
    echo "  $0 import k8s-master1"
    echo "  $0 import-all"
    echo "  $0 virt-manager"
}

# 获取虚拟机列表
get_vm_list() {
    if [ -d "$VM_IMAGE_DIR" ]; then
        find "$VM_IMAGE_DIR" -name "*.info" -exec basename {} .info \; 2>/dev/null | sort
    fi
}

# 检查虚拟机是否存在
vm_exists() {
    local vm_name="$1"
    [ -f "$VM_IMAGE_DIR/${vm_name}.info" ]
}

# 检查虚拟机是否运行
vm_running() {
    local vm_name="$1"
    local pid_file="$VM_IMAGE_DIR/${vm_name}.pid"
    [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null
}

# 获取虚拟机信息
get_vm_info() {
    local vm_name="$1"
    local info_file="$VM_IMAGE_DIR/${vm_name}.info"
    
    if [ -f "$info_file" ]; then
        source "$info_file"
        echo "VM_NAME=$VM_NAME"
        echo "VM_TYPE=$VM_TYPE"
        echo "VM_IP=$VM_IP"
        echo "VM_MAC=$VM_MAC"
        echo "VNC_PORT=$VNC_PORT"
        echo "SSH_PORT=$SSH_PORT"
        echo "VM_DISK=$VM_DISK"
        echo "CREATED_TIME=$CREATED_TIME"
    fi
}

# 列出所有虚拟机
list_vms() {
    echo "$(blue '=== 虚拟机列表 ===')"
    echo
    
    local vms=($(get_vm_list))
    
    if [ ${#vms[@]} -eq 0 ]; then
        echo "$(yellow '没有找到虚拟机')"
        return
    fi
    
    printf "%-20s %-10s %-15s %-10s %-10s %s\n" "虚拟机名称" "类型" "IP地址" "状态" "VNC端口" "创建时间"
    echo "---------------------------------------------------------------------------------"
    
    for vm_name in "${vms[@]}"; do
        local info_file="$VM_IMAGE_DIR/${vm_name}.info"
        if [ -f "$info_file" ]; then
            source "$info_file"
            local status
            if vm_running "$vm_name"; then
                status="$(green '运行中')"
            else
                status="$(red '已停止')"
            fi
            printf "%-20s %-10s %-15s %-10s %-10s %s\n" "$VM_NAME" "$VM_TYPE" "$VM_IP" "$status" "$VNC_PORT" "$CREATED_TIME"
        fi
    done
}

# 显示虚拟机状态
show_status() {
    local vm_name="$1"
    
    if [ -z "$vm_name" ]; then
        list_vms
        return
    fi
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    echo "$(blue "=== $vm_name 状态 ===")"
    echo
    
    local info_file="$VM_IMAGE_DIR/${vm_name}.info"
    source "$info_file"
    
    echo "虚拟机名称: $VM_NAME"
    echo "虚拟机类型: $VM_TYPE"
    echo "IP地址: $VM_IP"
    echo "MAC地址: $VM_MAC"
    echo "VNC端口: $VNC_PORT"
    echo "SSH端口: $SSH_PORT"
    echo "磁盘文件: $VM_DISK"
    echo "创建时间: $CREATED_TIME"
    
    if vm_running "$vm_name"; then
        echo "运行状态: $(green '运行中')"
        local pid=$(cat "$VM_IMAGE_DIR/${vm_name}.pid")
        echo "进程ID: $pid"
        echo "内存使用: $(ps -p $pid -o rss= 2>/dev/null | awk '{print int($1/1024)}')MB"
    else
        echo "运行状态: $(red '已停止')"
    fi
    
    if [ -f "$VM_DISK" ]; then
        local disk_size=$(du -h "$VM_DISK" | cut -f1)
        echo "磁盘大小: $disk_size"
    fi
}

# 启动虚拟机
start_vm() {
    local vm_name="$1"
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    if vm_running "$vm_name"; then
        echo "$(yellow "虚拟机 $vm_name 已经在运行")"
        return 0
    fi
    
    local start_script="$VM_IMAGE_DIR/start-${vm_name}.sh"
    if [ -f "$start_script" ]; then
        echo "启动虚拟机: $vm_name"
        "$start_script"
        sleep 2
        if vm_running "$vm_name"; then
            echo "$(green "✓ $vm_name 启动成功")"
        else
            echo "$(red "✗ $vm_name 启动失败")"
            return 1
        fi
    else
        echo "$(red "错误: 启动脚本不存在: $start_script")"
        return 1
    fi
}

# 停止虚拟机
stop_vm() {
    local vm_name="$1"
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    if ! vm_running "$vm_name"; then
        echo "$(yellow "虚拟机 $vm_name 已经停止")"
        return 0
    fi
    
    local pid_file="$VM_IMAGE_DIR/${vm_name}.pid"
    local monitor_file="$VM_IMAGE_DIR/${vm_name}.monitor"
    
    echo "停止虚拟机: $vm_name"
    
    local pid=$(cat "$pid_file")
    
    # 尝试优雅关机
    if [ -S "$monitor_file" ]; then
        echo "发送关机信号..."
        echo "system_powerdown" | socat - "$monitor_file" 2>/dev/null || true
        
        # 等待10秒
        local count=0
        while [ $count -lt 10 ] && vm_running "$vm_name"; do
            sleep 1
            count=$((count + 1))
        done
    fi
    
    # 如果还在运行，强制终止
    if vm_running "$vm_name"; then
        echo "强制终止虚拟机..."
        kill "$pid" 2>/dev/null || true
        sleep 1
    fi
    
    rm -f "$pid_file"
    echo "$(green "✓ $vm_name 已停止")"
}

# 重启虚拟机
restart_vm() {
    local vm_name="$1"
    
    echo "重启虚拟机: $vm_name"
    stop_vm "$vm_name"
    sleep 2
    start_vm "$vm_name"
}

# 启动安装模式
install_vm() {
    local vm_name="$1"
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    if vm_running "$vm_name"; then
        echo "$(yellow "虚拟机 $vm_name 正在运行，先停止...")"
        stop_vm "$vm_name"
    fi
    
    local install_script="$VM_IMAGE_DIR/install-${vm_name}.sh"
    if [ -f "$install_script" ]; then
        echo "启动虚拟机安装模式: $vm_name"
        "$install_script"
        
        local info_file="$VM_IMAGE_DIR/${vm_name}.info"
        if [ -f "$info_file" ]; then
            source "$info_file"
            echo "$(green "✓ $vm_name 安装模式已启动")"
            echo "VNC连接: localhost:$VNC_PORT"
        fi
    else
        echo "$(red "错误: 安装脚本不存在: $install_script")"
        return 1
    fi
}

# 显示VNC连接信息
show_connect_info() {
    local vm_name="$1"
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    local info_file="$VM_IMAGE_DIR/${vm_name}.info"
    source "$info_file"
    
    echo "$(blue "=== $vm_name 连接信息 ===")"
    echo
    echo "VNC连接: localhost:$VNC_PORT"
    echo "SSH端口: $SSH_PORT (如果已配置端口转发)"
    echo "IP地址: $VM_IP"
    echo
    
    if vm_running "$vm_name"; then
        echo "$(green '虚拟机正在运行，可以连接')"
        echo
        echo "VNC客户端连接命令示例:"
        echo "  vncviewer localhost:$VNC_PORT"
        echo "  或使用任何VNC客户端连接到 localhost:$VNC_PORT"
    else
        echo "$(red '虚拟机未运行，请先启动虚拟机')"
    fi
}

# 连接到监控器
connect_monitor() {
    local vm_name="$1"
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    if ! vm_running "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 未运行")"
        return 1
    fi
    
    local monitor_file="$VM_IMAGE_DIR/${vm_name}.monitor"
    
    if [ -S "$monitor_file" ]; then
        echo "连接到 $vm_name 监控器..."
        echo "输入 'help' 查看可用命令，输入 'quit' 退出"
        socat - "$monitor_file"
    else
        echo "$(red "错误: 监控器文件不存在: $monitor_file")"
        return 1
    fi
}

# 删除虚拟机
delete_vm() {
    local vm_name="$1"
    
    if ! vm_exists "$vm_name"; then
        echo "$(red "错误: 虚拟机 $vm_name 不存在")"
        return 1
    fi
    
    echo "$(red "警告: 即将删除虚拟机 $vm_name 及其所有数据")"
    read -p "确认删除? (输入 'DELETE' 确认): " confirm
    
    if [ "$confirm" != "DELETE" ]; then
        echo "$(yellow '删除已取消')"
        return 0
    fi
    
    # 停止虚拟机
    if vm_running "$vm_name"; then
        echo "停止虚拟机..."
        stop_vm "$vm_name"
    fi
    
    # 删除相关文件
    echo "删除虚拟机文件..."
    rm -f "$VM_IMAGE_DIR/${vm_name}.info"
    rm -f "$VM_IMAGE_DIR/${vm_name}.pid"
    rm -f "$VM_IMAGE_DIR/${vm_name}.monitor"
    rm -f "$VM_IMAGE_DIR/start-${vm_name}.sh"
    rm -f "$VM_IMAGE_DIR/install-${vm_name}.sh"
    
    local info_file="$VM_IMAGE_DIR/${vm_name}.info"
    if [ -f "$info_file" ]; then
        source "$info_file"
        if [ -f "$VM_DISK" ]; then
            rm -f "$VM_DISK"
            echo "删除磁盘文件: $VM_DISK"
        fi
    fi
    
    echo "$(green "✓ 虚拟机 $vm_name 已删除")"
}

# 显示网络状态
show_network() {
    echo "$(blue '=== 网络状态 ===')"
    echo
    
    if ip link show "$BRIDGE_NAME" >/dev/null 2>&1; then
        echo "$(green "✓ 网桥 $BRIDGE_NAME 已配置")"
        ip addr show "$BRIDGE_NAME" | grep inet
    else
        echo "$(red "✗ 网桥 $BRIDGE_NAME 未配置")"
        echo "请运行: sudo ./setup-network.sh"
    fi
    
    echo
    echo "IP转发状态:"
    if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "1" ]; then
        echo "$(green '✓ IP转发已启用')"
    else
        echo "$(red '✗ IP转发未启用')"
    fi
}

# 清理所有虚拟机
cleanup_all() {
    echo "$(red "警告: 即将停止并删除所有虚拟机")"
    read -p "确认清理? (输入 'CLEANUP' 确认): " confirm
    
    if [ "$confirm" != "CLEANUP" ]; then
        echo "$(yellow '清理已取消')"
        return 0
    fi
    
    local vms=($(get_vm_list))
    
    for vm_name in "${vms[@]}"; do
        echo "删除虚拟机: $vm_name"
        if vm_running "$vm_name"; then
            stop_vm "$vm_name"
        fi
        
        # 删除文件（不需要确认）
        rm -f "$VM_IMAGE_DIR/${vm_name}.info"
        rm -f "$VM_IMAGE_DIR/${vm_name}.pid"
        rm -f "$VM_IMAGE_DIR/${vm_name}.monitor"
        rm -f "$VM_IMAGE_DIR/start-${vm_name}.sh"
        rm -f "$VM_IMAGE_DIR/install-${vm_name}.sh"
        
        local info_file="$VM_IMAGE_DIR/${vm_name}.info"
        if [ -f "$info_file" ]; then
            source "$info_file"
            if [ -f "$VM_DISK" ]; then
                rm -f "$VM_DISK"
            fi
        fi
    done
    
    echo "$(green '✓ 所有虚拟机已清理')"
}

# 主程序
main() {
    if [ $# -eq 0 ]; then
        show_help
        exit 0
    fi
    
    local command="$1"
    shift
    
    case "$command" in
        "list")
            list_vms
            ;;
        "status")
            show_status "$1"
            ;;
        "start")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            start_vm "$1"
            ;;
        "stop")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            stop_vm "$1"
            ;;
        "restart")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            restart_vm "$1"
            ;;
        "install")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            install_vm "$1"
            ;;
        "connect")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            show_connect_info "$1"
            ;;
        "monitor")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            connect_monitor "$1"
            ;;
        "delete")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            delete_vm "$1"
            ;;
        "import")
            if [ -z "$1" ]; then
                echo "$(red '错误: 请指定虚拟机名称')"
                exit 1
            fi
            import_to_virtmanager "$1"
            ;;
        "import-all")
            import_all_to_virtmanager
            ;;
        "virt-manager")
            start_virtmanager_gui
            ;;
        "network")
            show_network
            ;;
        "cleanup")
            cleanup_all
            ;;
        "help"|"--help"|"-h")
            show_help
            ;;
        *)
            echo "$(red "错误: 未知命令 '$command'")"
            echo
            show_help
            exit 1
            ;;
    esac
}

# 运行主程序
main "$@"